/* * * * M A P V I S I O N   L I C E N S E  *****************************************************************
 *
 * This MapVision software is © Filip Zavadil 2013. It is licensed under the LGPL license.
 * This MapVision software dynamically links to unmodified Qt5 Library.
 *
 * The Qt5 Library is © 2013 Qt® and/or its subsidiary(-ies), and is licensed under the
 * GNU Lesser General Public License version 2.1 with Qt® LGPL exception version 1.1.
 * Qt5 library is free software; you can redistribute it and/or modify it under the terms of the
 * GNU Lesser General Public License, version 2.1, as published by the Free Software Foundation.
 * Qt5 library is provided “AS IS”, without WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR
 * IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
 *
 * As an additional permission to the GNU Lesser General Public License version 2.1, the object
 * code form of a “work that uses the Library” may incorporate material from a header file that is
 * part of the Library. You may distribute such object code under terms of your choice,
 * provided that: (i) the header files of the Library have not been modified; and (ii)
 * the incorporated material is limited to numerical parameters, data structure layouts, accessors,
 * macros, inline functions and templates; and (iii) you comply with the terms of Section 6 of the
 * GNU Lesser General Public License version 2.1.
 *
 * Moreover, you may apply this exception to a modified version of the Library, provided that such
 * modification does not involve copying material from the Library into the modified Library’s header
 * files unless such material is limited to (i) numerical parameters; (ii) data structure layouts;
 * (iii) accessors; and (iv) small macros, templates and inline functions of five lines or less in length.
 *
 * Furthermore, you are not required to apply this additional permission to a modified version of the Library.
 *
 * You should have received a copy of the GNU Lesser General Public License along with this package;
 * if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA

 * The source code for Qt 5.X SDK is available from Qt Project here:
 * http://download.qt-project.org/official_releases/qtcreator/2.7/2.7.0/qt-creator-2.7.0-src.zip.
 *
 * ****************************** M A P V I S I O N    S O F T W A R E  ************************************
 *
 * Author:       Filip Zavadil
 * Description:  Software for displaying and exporting map tiles.
 * The sources and executables of MapVision software are available:
 *    - from project hosting on CodePlex.com :   http://mapvision.codeplex.com
 *    - from GIT repositories on Gitorious.org:  https://gitorious.org/mapvision
 * Visit MapVision fanpage on Facebook.com:      https://www.facebook.com/pages/Mapvision/631827753513935
 *
 * *********************************************************************************************************
*/

#include "listwidget.h"
#include <QDebug>
#include <QContextMenuEvent>
#include <QMenu>
#include <QAction>
#include "layer.h"

ListWidget::ListWidget(QWidget *parent, QList<Layer *> *layers_) :
    QListWidget(parent), layers(layers_)
{
    lastId=0;
    this->setDragDropMode(QAbstractItemView::InternalMove);
    this->setDefaultDropAction(Qt::MoveAction);
    this->setSortingEnabled(false);
    this->setContextMenuPolicy(Qt::DefaultContextMenu);
    connect(this,SIGNAL(itemChanged(QListWidgetItem*)),this,SLOT(itemChanged(QListWidgetItem*)));


}


void ListWidget::dropEvent(QDropEvent *event)
{
    if (layers->size() == this->count()+1)  layers->pop_back();
    QListWidgetItem * itemSel =this->selectedItems()[0];
    emit QListWidget::dropEvent(event);
    updateOrder(itemSel);
}

void ListWidget::updateOrder(QListWidgetItem * item_old)
{

    for (int i=0;i<this->count();i++)
    {
        QListWidgetItem * item = this->item(i);
        if (item != item_old)
        {
            this->getLayer(item->data(Qt::UserRole).toInt())->changeZvalue(-this->row(item));
        }
    }
}

void ListWidget::updateOrder()
{
    for (int i=0;i<this->count();i++)
    {
        QListWidgetItem * item = this->item(i);
        this->getLayer(item->data(Qt::UserRole).toInt())->changeZvalue(-this->row(item));
    }
}


void ListWidget::mousePressEvent(QMouseEvent *event)
{
    QListWidget::mousePressEvent(event);
}

void ListWidget::mouseReleaseEvent(QMouseEvent *e)
{
    QListWidget::mouseReleaseEvent(e);
}

int ListWidget::getId()
{
    lastId++;
    return lastId;
}

QListWidgetItem *ListWidget::getListWidgetItem(int id)
{
    QListWidgetItem * item = new QListWidgetItem;
    foreach (QListWidgetItem * item_, this->findItems(".*",Qt::MatchRegExp)) {
        if (item_->data(Qt::UserRole)==id)
        {
            return item_;
        }
    }
    return item;

}

void ListWidget::contextMenuEvent(QContextMenuEvent *event)
{
    QListWidgetItem * item = this->itemAt(event->pos());
    if (item)
    {
        Layer * layer = this->getLayer(item->data(Qt::UserRole).toInt());
        QMenu *contextMenu = new QMenu(this);
        QString selectText;

        if (layer->layerGroup->flags() == (QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemIsMovable)){
            selectText=tr("deselect");
        } else {

            selectText=tr("select");
        }


        actPreferences = new QAction(QIcon("map.png"), tr("Preferences"),this);
        actClose = new QAction(QIcon("map.png"), tr("Close"),this);
        actZoomTo = new QAction(QIcon("map.png"), tr("Go to Origin"),this);
        actSelectAll = new QAction(QIcon("map.png"), selectText,this);


        connect(actPreferences,SIGNAL(triggered()),layer,SLOT(getPreferences()));

        connect(actClose,SIGNAL(triggered()),this,SLOT(deleteItem()));

        connect(actZoomTo,SIGNAL(triggered()),this,SLOT(zoomToLayer()));

        connect(actSelectAll,SIGNAL(triggered()),this,SLOT(selecting()));


        contextMenu->addAction(actPreferences);
        contextMenu->addAction(actZoomTo);
        contextMenu->addAction(actSelectAll);
        contextMenu->addAction(actClose);

        contextMenu->exec(event->globalPos());

    }
}


void ListWidget::itemChanged(QListWidgetItem *item)
{
    if (item->data(Qt::UserRole).toInt())
    {
        Layer * selected;

        qDebug()<<item->data(Qt::UserRole);

        selected=this->getLayer(item->data(Qt::UserRole).toInt());

        bool visible = (item->checkState()== Qt::Checked) ? true : false;

        if (selected != 0) selected->setVisible(visible);
    }
}

void ListWidget::deleteItem()
{
    QListWidgetItem* item = this->selectedItems()[0];
    if (item)
    {

        Layer * layer =this->getLayer(item->data(Qt::UserRole).toInt());

        layer->sceneHasCleared();

        delete layer->layerGroup;

        delete layer;

        if (layers->removeOne(this->getLayer(item->data(Qt::UserRole).toInt()))) qDebug()<<"mesage removed";
        this->removeItemWidget(item);
        item->~QListWidgetItem();

    }
}

void ListWidget::selecting()
{
    QListWidgetItem* item = this->selectedItems()[0];
    Layer * layer = getLayer(item->data(Qt::UserRole).toInt());


    if (layer->layerGroup->flags() == (QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemIsMovable)){
        layer->layerGroup->setSelected(false);
        layer->layerGroup->setFlags(NULL);
    } else {

        layer->layerGroup->setFlag(QGraphicsItem::ItemIsSelectable,true);
        layer->layerGroup->setFlag(QGraphicsItem::ItemIsMovable,true);
        layer->layerGroup->setSelected(true);
    }
}

void ListWidget::zoomToLayer()
{
    QListWidgetItem* item = this->selectedItems()[0];
    Layer * layer = getLayer(item->data(Qt::UserRole).toInt());
    layer->getMapView()->setZoom(layer->getZoomOrigin());
    layer->getMapView()->setCenterLonLat(layer->getLonlatOrigin());
}


Layer *ListWidget::getLayer(int id)
{
    Layer* layer;
    foreach (layer, *layers) {
        if (layer->getId()==id)
        {
            return layer;
        }
    }

    return layer;
}

